package com.hejia.alauda.service;

import com.hejia.alauda.entity.*;
import com.hejia.alauda.entity.example.*;
import com.hejia.alauda.persistence.mybatis.*;
import com.hejia.alauda.utils.Pager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;

import javax.annotation.Resource;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.*;


@Service
public class PageServiceImpl implements PageService{
	
	@Resource
	private FreeMarkerConfig freemarkerConfig;

	@Resource
	private PageMapper pageMapper;
	
	@Resource
	private PageCategoryMapper pageCategoryMapper;
	
	@Resource
	private PageTemplateMapper pageTemplateMapper;

    @Resource
    private LinksMapper mapper;

    @Resource
    private MediaInstitutionMapper mediaInstitutionMapper;

    @Resource
    private MediumMapper mediumMapper;

    @Override
	public Page findPageById(Long id) {
		return pageMapper.selectByPrimaryKey(id);
	}
	
	@Override
	public Page findPageByName(String name) {
		PageExample example = new PageExample();
		example.createCriteria().addCriterion("name=", name)
								.addCriterion("deleted=", false);
		return pageMapper.selectOneByExample(example);
	}

	@Override
	public String renderArticle(Page page) {
		return getHtml(page);
	}
	
	
	public String getHtml(Page page) {
		if (page == null) {
			return null;
		}
		if (page.getPageTemplate() == null) {
			return page.getContent();
		}

		Map<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap.put("page", page);
		parameterMap.put("templateContent", page.getPageTemplate()
				.getContent());
		return resolvedAsHtml(parameterMap);
	}
	
	
	public String resolvedAsHtml(Map<String, Object> parameterMap) {
		if (parameterMap == null || parameterMap.get("templateContent") == null) {
			return null;
		}
		try {

			String templateContent = parameterMap.get("templateContent")
					.toString();

			StringWriter writer = new StringWriter();
			new freemarker.template.Template("", new StringReader(
					templateContent), freemarkerConfig.getConfiguration())
					.process(parameterMap, writer);
			return writer.toString();
		} catch (Exception e) {
			return null;
		}
	}
	
	@Override
	@Transactional
	public boolean savePage(Page page) {
		return pageMapper.insert(page)>0;
	}

	@Override
	@Transactional
	public boolean updatePage(Page page) {
		return pageMapper.updateByPrimaryKey(page)>0;
	}

	@Override
	public boolean deletePage(Long id) {
		 Page page = pageMapper.selectByPrimaryKey(id);
		 if (page != null) {
			 return pageMapper.deleteByPrimaryKey(page)>0;
		}
		return false;
	}
	@Override
	public Pager<Page> findAllPager(Pager<Page> pager, PageExample example) {
		if (example == null) 
			example  =  new PageExample();
		  example.appendCriterion("deleted = ", false);
	      pager.setList(pageMapper.selectByExample(example, pager));
	      pager.setTotalCount(pageMapper.countByExample(example));
		return pager;
	}

	@Override
	@Transactional
	public boolean savePageCategory(PageCategory pageCategory) {
		return pageCategoryMapper.insert(pageCategory)>0;
	}

	@Override
	@Transactional
	public boolean updatePageCategory(PageCategory pageCategory) {
		return pageCategoryMapper.updateByPrimaryKey(pageCategory)>0;
	}

	@Override
	@Transactional
	public boolean updateSequncePageCategory(List<PageCategory> pageCategoryList) {
	 
		return false;
	}

	@Override
	@Transactional
	public boolean savePageTemplate(PageTemplate page) {
		return pageTemplateMapper.insert(page)>0;
	}

	@Override
	@Transactional
	public boolean updatePageTemplate(PageTemplate page) {
		return pageTemplateMapper.updateByPrimaryKey(page)>0;
	}



	@Override
	public Pager<PageCategory> findAllPageCategory(Pager<PageCategory> pager,
			PageCategoryExample example) {
		if (example == null) 
			example  =  new PageCategoryExample();
		List<PageCategory> pageCategoryList = pageCategoryMapper.selectPageCategoryCount();
		//只对大类进行分页
		Map<Long, PageCategory> categoryMap = this.handlePageCategory(pageCategoryList);
		List<PageCategory> arrayList =   new ArrayList<PageCategory>(categoryMap.values());
		int listSize = arrayList.size();
		int fromIndex  = pager.getStartNumber();
		int toIndex    = pager.getStartNumber()+pager.getEndNumber();
		if (fromIndex>listSize) 
			return  pager;
		if (toIndex > listSize) {
			toIndex = listSize;
		}
	     pager.setList(arrayList.subList(fromIndex, toIndex));
	     pager.setTotalCount(categoryMap.size());
		return pager;
	}
	
	private Map<Long, PageCategory> handlePageCategory(List<PageCategory> pageCategoryList) {
		Map<Long, PageCategory> categoryMap  = new LinkedHashMap<Long, PageCategory>();
		Iterator<PageCategory> iterator = pageCategoryList.iterator();
		//暂时获取大类
		while ( iterator.hasNext()) {
			PageCategory category = iterator.next();
			if (category.getParent()==null) {
				categoryMap.put(category.getId(), category);
				iterator.remove();
			}			
		}
		//统计大类的数量，并向大类中注入所属的小类
		for (PageCategory category : pageCategoryList) {
			PageCategory categoryLittle = categoryMap.get(category.getParent().getId());
			if (categoryLittle != null) {
				categoryLittle.setCount(categoryLittle.getCount()+category.getCount());
				List<PageCategory> categorys = categoryLittle.getChildren();
				categorys.add(category);
			}
		} 
		return  categoryMap;
	}

	@Override
	public Pager<PageTemplate> findAllPageTemplate(Pager<PageTemplate> pager,
			PageTemplateExample example) {
		if (example == null) 
			example  =  new PageTemplateExample();
	      pager.setList(pageTemplateMapper.selectByExample(example, pager));
	      pager.setTotalCount(pageTemplateMapper.countByExample(example));
		return pager;
	}



	@Override
	public PageCategory findPageCategoryById(Long id) {
		return pageCategoryMapper.selectByPrimaryKey(id);
	}



	@Override
	public PageTemplate findPageTemplateById(Long id) {
		return pageTemplateMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<PageCategory> findAllPageCategory() {
		List<PageCategory> pageCategoryList = pageCategoryMapper.selectPageCategoryCount();
		Map<Long, PageCategory> categoryMap = this.handlePageCategory(pageCategoryList);
		return new ArrayList<>(categoryMap.values());
	}

	@Override
	public List<PageTemplate> findAllPageTemplate() {
		return (List<PageTemplate>) pageTemplateMapper.selectByExample(new PageTemplateExample(), null);
	}

    @Override
    public List<Links> getParameters() {
        LinksExample exp = new LinksExample();
        return mapper.selectByExample(exp, null);
    }

    @Override
    public boolean saveLinks(Links links) {
        return mapper.insert(links) > 0;
    }

    @Override
    public Links getLinksById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public boolean updateLinks(Links links) {
        return mapper.updateByPrimaryKey(links) > 0;
    }

    @Override
    public boolean deleteLinks(Long id) {
        Links links = mapper.selectByPrimaryKey(id);
        return mapper.deleteByPrimaryKey(links) > 0;
    }

    @Override
    public Pager<MediaInstitution> findAllMediaInstitution(
            Pager<MediaInstitution> pager) {
        return findAllMediaInstitution(pager, new MediaInstitutionExample());
    }

    @Override
    public Pager<MediaInstitution> findAllMediaInstitution(
            Pager<MediaInstitution> pager, MediaInstitutionExample example) {
        example.setOrderByClause("id desc");
        pager.setList(mediaInstitutionMapper.selectByExample(example, pager));
        pager.setTotalCount(mediaInstitutionMapper.countByExample(example));
        return pager;
    }

    @Override
    public boolean saveMediaInstitution(MediaInstitution mediaInstitution) {
        mediaInstitution.setCreateDate(new Date());
        mediaInstitution.setModifyDate(new Date());
        return mediaInstitutionMapper.insert(mediaInstitution) > 0;
    }

    @Override
    public MediaInstitution getMediaInstitutionById(Long id) {
        return mediaInstitutionMapper.selectByPrimaryKey(id);
    }

    @Override
    public boolean modifyMediaInstitution(MediaInstitution mediaInstitution) {
        MediaInstitution mediaInstitution2 = mediaInstitutionMapper
                .selectByPrimaryKey(mediaInstitution.getId());
        mediaInstitution2.setModifyDate(new Date());
        mediaInstitution2.setMedium(mediaInstitution.getMedium());
        mediaInstitution2.setLogo(mediaInstitution.getLogo());
        mediaInstitution2.setSequence(mediaInstitution.getSequence());
        mediaInstitution2.setIsTop(mediaInstitution.getIsTop());
        return mediaInstitutionMapper.updateByPrimaryKey(mediaInstitution2) > 0;
    }

    @Override
    public boolean deleteMediaInstitution(Long id) {
        MediaInstitution mediaInstitution = mediaInstitutionMapper
                .selectByPrimaryKey(id);
        return mediaInstitutionMapper.deleteByPrimaryKey(mediaInstitution) > 0;
    }

    @Override
    public List<MediaInstitution> getMediumnameList() {
        MediaInstitutionExample exp = new MediaInstitutionExample();
        Pager<MediaInstitution> pager = new Pager<MediaInstitution>();
        return mediaInstitutionMapper.selectByExample(exp, pager);
    }

    @Override
    public List<MediaInstitution> getMediumByCondition() {
        MediaInstitutionExample exp = new MediaInstitutionExample();
        exp.appendCriterion("link!=", "");
        exp.appendCriterion("isTop=true");
        exp.setOrderByClause("sequence");
        Pager<MediaInstitution> pager = new Pager<MediaInstitution>();
        return mediaInstitutionMapper.selectByExample(exp, pager);
    }

    @Override
    public Pager<Medium> findAllMedium(Pager<Medium> pager) {
        return findAllMedium(null, pager);
    }

    @Override
    public Pager<Medium> findAllMedium(MediumExample example,
                                       Pager<Medium> pager) {
        if (example == null) {
            example = new MediumExample();
        }

        example.setOrderByClause("reportDate desc,id desc");
        pager.setList(mediumMapper.selectByExample(example, pager));
        pager.setTotalCount(mediumMapper.countByExample(example));
        return pager;
    }

    @Override
    public boolean saveMedium(Medium medium) {
        medium.setCreateDate(new Date());
        medium.setModifyDate(new Date());
        medium.setSource(medium.getInstitution().getMedium());
        boolean sucess = mediumMapper.insert(medium) > 0;
		/*
		 * 更新媒体机构链接
		 */
        if (sucess) {
            updateLink(medium);
        }
        return sucess;
    }

    @Override
    public Medium getMediumById(Long id) {
        return mediumMapper.selectByPrimaryKey(id);
    }

    /**
     * 更新媒体机构链接
     *
     * @param medium
     */
    private void updateLink(Medium medium) {
        if ("top".equals(medium.getTop())) {
            mediumMapper
                    .setTop(medium.getInstitution().getId(), medium.getId());
            MediaInstitution institution = mediaInstitutionMapper
                    .selectByPrimaryKey(medium.getInstitution().getId());
            institution.setLink(medium.getSourceUrl());
            mediaInstitutionMapper.updateByPrimaryKey(institution);
        }
    }

    @Override
    public boolean modifyMedium(Medium medium) {
        Medium medium2 = mediumMapper.selectByPrimaryKey(medium.getId());
        medium2.setModifyDate(new Date());
        medium2.setTitle(medium.getTitle());
        medium2.setReportDate(medium.getReportDate());
        medium2.setSource(medium.getInstitution().getMedium());
        medium2.setIntroduction(medium.getIntroduction());
        medium2.setPictureUrl(medium.getPictureUrl());
        medium2.setContent(medium.getContent());
        medium2.setTop(medium.getTop());
        medium2.setSourceUrl(medium.getSourceUrl());
        medium2.setInstitution(medium.getInstitution());
        medium2.setPublish(medium.getPublish());

        boolean sucess = mediumMapper.updateByPrimaryKey(medium2) > 0;
		/*
		 * 更新媒体机构链接
		 */
        if (sucess) {
            updateLink(medium);
        }
        return sucess;
    }

    @Override
    public boolean deleteMedium(Long id) {
        Medium medium = mediumMapper.selectByPrimaryKey(id);
        return mediumMapper.deleteByPrimaryKey(medium) > 0;
    }

}
